import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lishuo
 * Date: 2023-04-19
 * Time: 20:47
 */
public class SearchDestfile {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 1、用户指定根目录
        System.out.println("请输入要扫描的根目录（绝对路径 OR 相对路径):");
        String rootDirPath = scanner.nextLine();
        File rootDir = new File(rootDirPath);

        // 判断输入目录是否有效
        if (!rootDir.isDirectory()) {
            // 如果输入为无效目录，直接返回
            System.out.println("您输入的根目录不存在或者为非法目录，程序退出！");
            return;
        }

        // 2、用户输入关键词
        System.out.println("请输入需要查找的关键词：");
        String keyWord = scanner.nextLine();

        // 用来存储满足条件的 file 对象
        List<File> result = new ArrayList<>();

        // 3、递归的进行目录/文件的遍历
        searchKey(rootDir,keyWord,result);

        // 4、打印结果集
        System.out.println();
        System.out.println("文件名或文件内容包含关键字“"+keyWord+"”的文件路径如下:");
        for (File file:result) {
            System.out.println(file.getAbsoluteFile());
        }
    }

    private static void searchKey(File directory, String keyWord,List<File> result) {
        // 返回当前目录下的所有文件
        File[] files = directory.listFiles();
        if (files==null || files.length==0) {
            // 如果目录不存在、或者被拒绝访问、或者为空，没必要继续递归，直接返回
            return;
        }

        // 目录里有内容, 就遍历目录中的每个元素
        for (File file:files) {
            if (file.isFile()) {
                // 打印扫描日志
                System.out.println("当前查找到:"+file.getAbsoluteFile());

                // 如果条目是普通文件，查看是否包含关键词
                // (1)先判断文件名是否含有关键词
                if (file.getName().contains(keyWord)) {
                    result.add(file);
                } else {
                    // (2)如果文件名不含关键词，再判断文件内容是否包含关键词
                    // 将内容以字符串形式读取出来
                    String content = readFile(file);
                    if (content.contains(keyWord)) {
                        result.add(file);
                    }
                }

            } else if (file.isDirectory()) {
                // 如果当前file是一个目录
                // 继续递归搜索
                searchKey(file,keyWord,result);
            } else {
                // 如果既不是普通文件，又不是目录，直接跳过
                continue;
            }
        }

    }

    private static String readFile(File file) {
        // 读取文件的整个内容, 返回出来.
        // 使用字符流来读取. 由于咱们匹配的是字符串, 此处只能按照字符流处理, 才是有意义的.
        StringBuilder stringBuilder = new StringBuilder();
        try (Reader reader = new FileReader(file)) {
            while (true) {
                int x = reader.read();
                if (x==-1) {
                    break;
                } else {
                    // 将读取到的字符添加到stringBuilder中，最后返回字符串
                    stringBuilder.append((char)x);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

}

